<template>
  <div class="crud-opts">
    <span class="crud-opts-left">
      <!--左侧插槽-->
      <slot name="left" />
      <a-button
        v-if="crud.optShow.add"
        v-permission="permission.add"
        class="filter-item"
        type="primary"
        icon="plus"
        @click="crud.toAdd"
      >
        新增
      </a-button>
      <a-button
        v-if="crud.optShow.edit"
        v-permission="permission.edit"
        class="filter-item"
        type="primary"
        icon="edit"
        :disabled="crud.selections.length !== 1"
        @click="crud.toEdit(crud.selections[0])"
      >
        修改
      </a-button>
      <a-button
        v-if="crud.optShow.del"
        slot="reference"
        v-permission="permission.del"
        class="filter-item"
        type="danger"
        icon="delete"
        :loading="crud.delAllLoading"
        :disabled="crud.selections.length === 0"
        @click="toDelete(crud.selections)"
      >
        删除
      </a-button>
      <!-- <a-button
        v-if="crud.optShow.download"
        :loading="crud.downloadLoading"
        :disabled="!crud.data.length"
        class="filter-item"
        size="mini"
        type="warning"
        icon="el-icon-download"
        @click="crud.doExport"
      >导出</a-button> -->
      <!--右侧-->
      <slot name="right" />
    </span>
    <a-button-group class="crud-opts-right">
      <a-button
        @click="toggleSearch()"
        icon="search"
      />
      <a-button
        @click="crud.refresh()"
        icon="redo"
      />
      <a-popover
        placement="bottomRight"
        width="150px"
      >
        <template slot="content">
          <a-checkbox
            v-model="allColumnsSelected"
            :indeterminate="allColumnsSelectedIndeterminate"
            @change="handleCheckAllChange"
          >
            全选
          </a-checkbox>
          <div
            v-for="item in tableColumns"
            :key="item.property"
          >
            <a-checkbox
              v-model="item.visible"
              @change="handleCheckedTableColumnsChange(item)"
            >
              {{ item.label }}
            </a-checkbox>
          </div>
        </template>
        <a-button icon="edit"></a-button>
      </a-popover>
    </a-button-group>
  </div>
</template>
<script>
import CRUD, { crud } from '@crud/crud';
import { Slime } from '@/mixins/slime';
function sortWithRef(src, ref) {
  const result = Object.assign([], ref);
  let cursor = -1;
  src.forEach((e) => {
    const idx = result.indexOf(e);
    if (idx === -1) {
      cursor += 1;
      result.splice(cursor, 0, e);
    } else {
      cursor = idx;
    }
  });
  return result;
}

export default {
  mixins: [crud(),Slime],
  props: {
    permission: {
      type: Object,
      default: () => {
        return {};
      },
    },
    hiddenColumns: {
      type: Array,
      default: () => {
        return [];
      },
    },
    ignoreColumns: {
      type: Array,
      default: () => {
        return [];
      },
    },
  },
  data() {
    return {
      tableColumns: [],
      allColumnsSelected: true,
      allColumnsSelectedIndeterminate: false,
      tableUnwatcher: null,
      // 忽略下次表格列变动
      ignoreNextTableColumnsChange: false,
    };
  },
  watch: {
    'crud.props.table'() {
      this.updateTableColumns();
      this.tableColumns.forEach((column) => {
        if (this.hiddenColumns.indexOf(column.property) !== -1) {
          column.visible = false;
          this.updateColumnVisible(column);
        }
      });
    },
    'crud.props.table.store.states.columns'() {
      this.updateTableColumns();
    },
  },
  created() {
    this.crud.updateProp('searchToggle', true);
  },
  methods: {
    updateTableColumns() {
      const table = this.crud.getTable();
      if (!table) {
        this.tableColumns = [];
        return;
      }
      let cols = null;
      const columnFilter = (e) =>
        e &&
        e.type === 'default' &&
        e.property &&
        this.ignoreColumns.indexOf(e.property) === -1;
      const refCols = table.columns.filter(columnFilter);
      if (this.ignoreNextTableColumnsChange) {
        this.ignoreNextTableColumnsChange = false;
        return;
      }
      this.ignoreNextTableColumnsChange = false;
      const columns = [];
      const fullTableColumns = table.$children
        .map((e) => e.columnConfig)
        .filter(columnFilter);
      cols = sortWithRef(fullTableColumns, refCols);
      cols.forEach((config) => {
        const column = {
          property: config.property,
          label: config.label,
          visible: refCols.indexOf(config) !== -1,
        };
        columns.push(column);
      });
      this.tableColumns = columns;
    },
    toDelete(datas) {
      this.$confirm(`确认删除选中的${datas.length}条数据?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(() => {
          this.crud.delAllLoading = true;
          this.crud.doDelete(datas);
        })
        .catch(() => {});
    },
    handleCheckAllChange(val) {
      if (val === false) {
        this.allColumnsSelected = true;
        return;
      }
      this.tableColumns.forEach((column) => {
        if (!column.visible) {
          column.visible = true;
          this.updateColumnVisible(column);
        }
      });
      this.allColumnsSelected = val;
      this.allColumnsSelectedIndeterminate = false;
    },
    handleCheckedTableColumnsChange(item) {
      let totalCount = 0;
      let selectedCount = 0;
      this.tableColumns.forEach((column) => {
        ++totalCount;
        selectedCount += column.visible ? 1 : 0;
      });
      if (selectedCount === 0) {
        this.crud.notify('请至少选择一列', CRUD.NOTIFICATION_TYPE.WARNING);
        this.$nextTick(function () {
          item.visible = true;
        });
        return;
      }
      this.allColumnsSelected = selectedCount === totalCount;
      this.allColumnsSelectedIndeterminate =
        selectedCount !== totalCount && selectedCount !== 0;
      this.updateColumnVisible(item);
    },
    updateColumnVisible(item) {
      const table = this.crud.props.table;
      const vm = table.$children.find((e) => e.prop === item.property);
      const columnConfig = vm.columnConfig;
      if (item.visible) {
        // 找出合适的插入点
        const columnIndex = this.tableColumns.indexOf(item);
        vm.owner.store.commit(
          'insertColumn',
          columnConfig,
          columnIndex + 1,
          null
        );
      } else {
        vm.owner.store.commit('removeColumn', columnConfig, null);
      }
      this.ignoreNextTableColumnsChange = true;
    },
    toggleSearch() {
      this.crud.props.searchToggle = !this.crud.props.searchToggle;
    },
  },
};
</script>

<style>
.crud-opts {
  padding: 4px 0;
  display: -webkit-flex;
  display: flex;
  align-items: center;
}
.crud-opts .crud-opts-right {
  margin-left: auto;
}
</style>
